package com.myjob.serviceImpl;

import cn.hutool.core.date.*;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.myjob.common.DubboConfig;
import com.myjob.config.Constants;
import com.myjob.config.MjServiceName;
import com.myjob.entity.*;
import com.myjob.enums.RedisEnums;
import com.myjob.enums.UserEnums;
import com.myjob.exception.DBOptionException;
import com.myjob.handler.JobHandler;
import com.myjob.mapper.*;
import com.myjob.response.Result;
import com.myjob.service.*;
import com.myjob.utils.RedisUtil;
import com.myjob.utils.UtilValidate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Chen Yuan
 * @create 2021-01-23  15:10
 */
@Service
@Slf4j
public class HrServiceImpl extends ServiceImpl<HrMapper, Hr> implements HrService {
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private HrMapper hrMapper;
	@Autowired
	private CompanyService companyService;
	@Autowired
	private MemberService memberService;
	@Autowired
	private RedisUtil redisUtil;

	@Reference(group = MjServiceName.JOB, version = DubboConfig.VERSION)
	private JobHandler jobHandler;

	@Override
	public Result selectHr(Integer currentPage, Integer pageSize, Long userId,
	                       Long companyId, String duty, String hrName, String searchValue) {
		Result result = null;

		// 按照 职责 查询所有相关的人事
		QueryWrapper<Hr> wrapper = new QueryWrapper<>();
		if (UtilValidate.isNotEmpty(duty)){
			wrapper.like("duty", duty);
		}
		if (UtilValidate.isNotEmpty(userId)){
			wrapper.eq("user_id", userId);
		}
		if (UtilValidate.isNotEmpty(companyId)){
			wrapper.eq("company_id",companyId);
		}

		Page<Hr> page = null;
		if (UtilValidate.isNotEmpty(pageSize)) {
			page = new Page<>(currentPage, pageSize);
		}else {
			page = new Page<>(currentPage, Constants.getPageSize());
		}

		IPage<Hr> hrIPage = hrMapper.selectPage(page, wrapper);
		List<Hr> hrs = hrIPage.getRecords();
		// 没结果直接返回
		if (UtilValidate.isEmpty(hrs)){
			return Result.succeed(hrIPage);
		}
		// 获取人事编号、公司编号列表
		List<String> allHrId = new ArrayList<>();
		for (Hr hr : hrs) {
			allHrId.add(hr.getUserId());
		}

		// 按照得到的人事列表查询基本信息
		hrs = getHrInfo(hrName, hrs, allHrId, searchValue);

		hrIPage.setRecords(hrs);

		result = Result.succeed(hrIPage);
		return result;
	}

	@Override
	@Transactional(rollbackFor = DBOptionException.class)
	public int addHr(Hr hr) {
		if (UtilValidate.isEmpty(hr)){
			return -1;
		}
		log.info("===== 开始添加 hr =====");
		hr.setHrStatus(UserEnums.ACCOUNT_STATUS.normal.getValue());
		Company company = companyService.selectOneCompany(hr.getCompanyId());

		if (UtilValidate.isEmpty(company)){
			return -2;
		}
		Member member = memberService.selectOneMember(company.getMemberLevel());

		log.info("{企业编号: "+hr.getCompanyId()+
				", 该企业 hr 人数: "+company.getHrNumber()+
				", 企业会员等级: "+company.getMemberLevel()+
				", hr 名额数: "+member.getHrNumber()+"}");

		if (company.getHrNumber() >= member.getHrNumber()){
			return -2;
		}
		company.setHrNumber(company.getHrNumber()+1);

		QueryWrapper<User> wrapper = new QueryWrapper<>();
		wrapper.eq("phone",hr.getPhone());
		wrapper.eq("email",hr.getEmail());
		User user = userMapper.selectOne(wrapper);
		if (UtilValidate.isEmpty(user)) {
			return -4;
		}
		log.info("{用户编号: "+user.getUserId()+
				", 该用户角色: "+user.getRole()+"}");
		if (!Objects.equals(user.getRole(), UserEnums.ROLE.candidate.getValue())){
			return -3;
		}

		String format = DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN);
		DateTime date = DateUtil.parse(format);
		log.info(String.valueOf(date));
		String photoPath = (String) redisUtil.get(RedisEnums.KEY_IN_REDIS.USER_PHOTO.getValue() + hr.getUuid() + ".png");
		user.setRole(UserEnums.ROLE.hr.getValue());
		user.setStatusUpdateTime(date);
		user.setStatusUpdateHandlerId(company.getCompanyId());
		user.setStatusUpdateHandlerName(company.getCompanyName());
		user.setPhoto(photoPath);


		hr.setUserId(user.getUserId());

		int update1 = companyService.updateCompany(company);
		int update2 = userMapper.updateById(user);
		int insert = hrMapper.insert(hr);
		return insert + update1 + update2;
	}

	@Override
	@Transactional(rollbackFor = {DBOptionException.class, RuntimeException.class, Exception.class})
	public int updateHr(Hr hr) {
		if (UtilValidate.isEmpty(hr)){
			return -1;
		}
		if (UtilValidate.isNotEmpty(hr.getHrStatus())){
			User user = new User();
			user.setUserId(hr.getUserId());
			if ("停止".equals(hr.getHrStatus())){
				//修改用户角色
				user.setRole("应聘者");
				user.setAccountStatus(UserEnums.ACCOUNT_STATUS.normal.getValue());
				// 将其下的岗位删除
				log.info("[Dubbo] - 远程调用开始 -> "+MjServiceName.JOB+" -> jobHandler -> deleteJobs");
				jobHandler.deleteJobs(hr.getUserId());
				log.info("[Dubbo] - 远程调用结束 -> =======================================================");
			}else {
				user.setAccountStatus(hr.getHrStatus());
			}
			log.info("[[ 修改企业状态 ]] --- 修改人事对应的用户状态");
			userMapper.updateById(user);
			log.info("[[ 修改企业状态 ]] --- 修改人事对应的岗位状态");
		}
		return hrMapper.updateById(hr);
	}

	@Override
	@Transactional(rollbackFor = {DBOptionException.class, RuntimeException.class, Exception.class})
	public int updateHrList(List<Hr> hrs, String status) {
		if (UtilValidate.isEmpty(hrs)) {
			return 0;
		}

		List<String> idList = hrs.stream().map(Hr::getUserId).collect(Collectors.toList());
		log.info("[[ 修改人事状态 ]] --- 将 id:"+hrs.get(0).getCompanyId()+" 的企业旗下所有的人事账号状态改为 "+status);

		UpdateWrapper<Hr> hrWrapper = new UpdateWrapper<>();
		UpdateWrapper<User> userWrapper = new UpdateWrapper<>();
		if(Objects.equals(status, UserEnums.ACCOUNT_STATUS.leave.getValue())){
			log.info("[[ 修改人事状态 ]] --- 修改对应的 User 状态");
			userWrapper.in("user_id", idList);
			User user = new User();
			user.setAccountStatus(UserEnums.ACCOUNT_STATUS.normal.getValue());
			userMapper.update(user, userWrapper);

			log.info("[[ 修改人事状态 ]] --- 修改其管理的岗位信息状态");
			log.info("[Dubbo] - 远程调用开始 -> "+MjServiceName.JOB+" -> jobHandler -> deleteJobListByHrIds");
			jobHandler.deleteJobListByHrIds(idList);
			log.info("[Dubbo] - 远程调用结束 -> =======================================================");
		}else {
			log.info("[[ 修改人事状态 ]] --- 修改其管理的岗位信息状态");
			log.info("[Dubbo] - 远程调用开始 -> "+MjServiceName.JOB+" -> jobHandler -> updateJobByHrIds");
//			log.info("======"+idList+". =="+status);
			jobHandler.updateJobByHrIds(idList, status);
			log.info("[Dubbo] - 远程调用结束 -> =======================================================");
		}
		log.info("[[ 修改人事状态 ]] --- 修改对应的 HR 状态");
		hrWrapper.in("user_id", idList);
		Hr hr = new Hr();
		hr.setHrStatus(status);
		return  hrMapper.update(hr, hrWrapper);
	}

	@Override
	@Transactional(rollbackFor = DBOptionException.class)
	public int deleteHr(String UserId) {
		if (UtilValidate.isEmpty(UserId)){
			return -1;
		}

		log.info("===== 开始删除 hr =====");
		QueryWrapper<Hr> wrapper = new QueryWrapper<>();
		wrapper.eq("user_id",UserId);
		Hr hr = hrMapper.selectOne(wrapper);
		Company company = companyService.selectOneCompany(hr.getCompanyId());
		if (company.getHrNumber() > 0){
			company.setHrNumber(company.getHrNumber()-1);
			companyService.updateCompany(company);
		}

		if (UtilValidate.isEmpty(company)){
			return -2;
		}
		User user = new User();
		user.setUserId(UserId);
		user.setRole(UserEnums.ROLE.candidate.getValue());
		int delete = hrMapper.deleteById(UserId);
		int update = userMapper.updateById(user);
		return delete + update;
	}


	/**
	 * 按照 得到的人事列表 查询对应的基本信息
	 * @param hrName 筛选条件，人事姓名
	 * @param hrs 人事列表
	 * @return 带有基本信息的人事信息列表
	 */
	private List<Hr> getHrInfo(String hrName, List<Hr> hrs, List<String> allHrId, String searchValue) {
		List<Hr> result = new ArrayList<>();

		Map<String, Hr> map = hrs.stream().collect(Collectors.toMap(Hr::getUserId, Hr->Hr));

		QueryWrapper<User> wrapper = new QueryWrapper<>();
		if (UtilValidate.isNotEmpty(hrName)){
			wrapper.like("user_name", hrName);
		}
		if (UtilValidate.isNotEmpty(searchValue)){
			wrapper.like("user_name", searchValue);
		}
		wrapper.in("user_id", allHrId);
		List<User> users = userMapper.selectList(wrapper);
		log.info("==== 人事及对应的基本信息");
		log.info(map.toString());
		// 把查到的人事和基本信息一一对应
		for (User user : users) {
			Hr hr = map.get(user.getUserId());
			hr.setUser(user);
			result.add(hr);
		}
		return result;
	}
}
